package com.computergames.server.server.handler;

import com.computergames.server.domain.ClientState;
import com.computergames.server.message.AbstractGameMessage;
import com.computergames.server.message.MoveRequestMessage;
import com.computergames.server.message.MoveResponseMessage;
import com.computergames.server.message.cardMessage.AbstractCardMessage;
import com.computergames.server.message.chessMessage.AbstractChessMessage;
import com.computergames.server.server.session.RoomSessionFactory;
import com.computergames.server.service.Interface.CheckAndUpdateClientState;
import com.computergames.server.service.getCurrentPlayerStrategy.Play_GetCurrentPlayerStrategySelector;
import com.computergames.server.util.RedisUtil;
import com.computergames.server.util.SpringUtil;
import com.computergames.server.service.GameStrategy.StrategySelector;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;


import java.util.List;
import java.util.Map;
import java.util.Set;

@ChannelHandler.Sharable
public class MoveRequestMessageHandler extends SimpleChannelInboundHandler<MoveRequestMessage> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, MoveRequestMessage msg) throws Exception {
        CheckAndUpdateClientState checkAndUpdateClientState = SpringUtil.getBean(CheckAndUpdateClientState.class);
        if(checkAndUpdateClientState.checkState(channelHandlerContext, ClientState.GAME_STARTED)){
            RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
            // 获取房间名
            String roomName = (String)channelHandlerContext.channel().attr(AttributeKey.valueOf("USER_ROOM")).get();
            // 获取当前玩家选择器
            Play_GetCurrentPlayerStrategySelector getCurrentPlayerStrategySelector = SpringUtil.getBean(Play_GetCurrentPlayerStrategySelector.class);
            // 获取房间成员通道
            List<Channel> channels = RoomSessionFactory.getRoomSession().getMembersChannel(roomName);
            // 获取房间成员
            Set<String> members = RoomSessionFactory.getRoomSession().getMembers(roomName);
            // 获取发送者
            String from = msg.getFrom();
            // 获取消息内容
            AbstractGameMessage content = msg.getContent();
            // 获取规则判定及数据存储策略选择器
            StrategySelector strategySelector = SpringUtil.getBean(StrategySelector.class);
            // 根据消息类型进行相应的处理
            if (content instanceof AbstractChessMessage) {
                // 判断是否是当前玩家的回合
                boolean isCurrentPlayer = getCurrentPlayerStrategySelector.select(roomName, from, content.getMessageType());
                if (!isCurrentPlayer) {
                    channelHandlerContext.writeAndFlush(new MoveResponseMessage(false, "不是你的回合"));
                    return;
                }
                // 根据消息类型选择对应的策略
                int result = strategySelector.select(content.getMessageType(), msg, roomName, channelHandlerContext);
                // 处理棋类游戏的消息
                if (result == 0) {
                    for(Channel channel : channels){
                        if (!channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get().equals(from)) {
                            channel.writeAndFlush(new MoveResponseMessage(msg.getFrom(), msg.getContent(), true, msg.getFrom() + "棋子放置成功"));
                        }else {
                            channel.writeAndFlush(new MoveResponseMessage(true, "棋子放置成功"));
                        }
                    }
                }
                else if(result == 1){
                    Map<Object, Object> record =  redisUtil.hmget(roomName+"棋谱");
                    List<String> recordList = (List<String>) record.get(roomName);
                    String recordStr = String.join(";", recordList);

                    String stage = (String)channelHandlerContext.channel().attr(AttributeKey.valueOf("USER_STAGE")).get();
                    Map<Object, Object> map = redisUtil.hmget(roomName + stage + "积分");
                    for(Channel channel : channels){
                        if (!channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get().equals(from)) {
                            channel.writeAndFlush(new MoveResponseMessage(msg.getFrom(), msg.getContent(), true, msg.getFrom() + "获胜"));
                        }else {
                            channel.writeAndFlush(new MoveResponseMessage(true, "胜利"));
                        }
                        channel.writeAndFlush(new MoveResponseMessage(true, "棋谱：" + recordStr));

                        String username = (String)channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get();
                        channel.writeAndFlush(new MoveResponseMessage(true, stage + "积分：" + map.get(username)+"排名：3"));
                        checkAndUpdateClientState.updateState(channel, ClientState.GAME_ENDED);
                    }
                }
                else {
                    for(Channel channel : channels){
                        if (channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get().equals(from)) {
                            channel.writeAndFlush(new MoveResponseMessage(false, "棋子放置异常"));
                        } else{
                            channel.writeAndFlush(new MoveResponseMessage(false, "对方棋子放置异常"));
                        }
                    }
                }
            } else if (content instanceof AbstractCardMessage) {
                // 获取玩家对应的方位
                String player = (String)channelHandlerContext.attr(AttributeKey.valueOf("POSITION")).get();
                // 判断是否是当前玩家的回合
                boolean isCurrentPlayer = getCurrentPlayerStrategySelector.select(roomName, player, content.getMessageType());
                if (!isCurrentPlayer) {
                    channelHandlerContext.writeAndFlush(new MoveResponseMessage(false, "不是你的回合"));
                    return;
                }
                // 根据消息类型选择对应的策略
                int result = strategySelector.select(content.getMessageType(), msg, roomName, channelHandlerContext);
                // 处理牌类游戏的消息
                if(result == 0){
                    for(Channel channel : channels){
                        if (!channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get().equals(from)) {
                            channel.writeAndFlush(new MoveResponseMessage(msg.getFrom(), msg.getContent(), true, msg.getFrom() + "出牌："+ msg.getContent().toString()));
                        }else{
                            channel.writeAndFlush(new MoveResponseMessage(true, "出牌成功"));
                        }
                    }
                }
                else if(result == 1){
                    Map<Object, Object> record =  redisUtil.hmget(roomName+"牌谱");
                    List<String> recordList = (List<String>) record.get(roomName);
                    String recordStr = String.join(";", recordList);

                    String stage = (String)channelHandlerContext.channel().attr(AttributeKey.valueOf("USER_STAGE")).get();
                    Map<Object, Object> map = redisUtil.hmget(roomName + stage + "积分");
                    for(Channel channel : channels){
                        if (!channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get().equals(from)) {
                            channel.writeAndFlush(new MoveResponseMessage(msg.getFrom(), msg.getContent(), true, msg.getFrom() + "获胜"));
                        }else{
                            channel.writeAndFlush(new MoveResponseMessage(true, "取得胜利"));
                        }
                        channel.writeAndFlush(new MoveResponseMessage(true, "牌谱：" + recordStr));

                        String username = (String)channel.attr(AttributeKey.valueOf("USER_IDENTIFIER")).get();
                        channel.writeAndFlush(new MoveResponseMessage(true, stage + "积分：" + map.get(username)));
                        checkAndUpdateClientState.updateState(channel, ClientState.GAME_ENDED);
                    }
                 }
            } else {
                // 如果content既不是AbstractChessMessage也不是AbstractCardMessage的实例，则抛出异常或进行错误处理
                throw new IllegalArgumentException("Unsupported message type: " + content.getClass().getName());
            }
        } else {
            channelHandlerContext.channel().writeAndFlush(new MoveResponseMessage(false, "游戏未开始"));
        }
    }
}
